// A sample player implemented in C++.  The sled just marches across
// the middle trying to capture pucks.  The bumpers try to push the
// pucks toward the center so they can be captured.
//
// ICPC Challenge
// Sturgill, Baylor University

#include "Util.h"
#include <vector>
#include <iostream>
#include <list>
#include <math.h>

using namespace std;

#define LEFT 1
#define RIGHT -1
#define BIGGEST_R 96.0
#define R_40 96.0
#define R_30 71.0
#define R_20 47.0
#define PI 3.141592654
#define NOTHING	0
#define CHANGE_DIRECTION 1
#define CIRCLE 2
#define CIRCLE_ENDED 3
#define GETTING_AWAY_EDGE 4
#define GIVING_UP 5

/** Simple representation for a puck. */
struct Puck {
	// Position of the puck.
	Vector2D pos;

	// Puck velocity
	Vector2D vel;

	// Puck color
	int color;
};

/** Simple representation for a bumper. */
struct Bumper {
	// Position of the bumper.
	Vector2D pos;

	// Bumper velocity
	Vector2D vel;
};

/** Simple representation for a sled. */
struct Sled {
	// Position of the sled.
	Vector2D pos;

	// Sled direction.
	double dir;
};

struct Bloco {
	int Peso;
};

// List of current sled, bumper and puck locations.  These are
// updated on every turn snapshot from the server.
vector< Puck > plist;
vector< Bumper > blist;
vector< Sled > slist;
vector< vector< Vector2D > > sHist;
int sledState = 0;
double sledDir;

// State of each bumper.
enum BumperState 
{
	MoveOponent,
	SpreadGray,
	SearchBlock,
	SpreadMine,
	DummyState
};

BumperState bstate[ 2 ] = { DummyState, MoveOponent};

// Latest target for each bumper, the bumper will try to move through
// this position to hit a puck toward the horizontal center.
Vector2D target[ 2 ];
Vector2D sledPM[ 2 ];

// How much longer the bumper has to pursue its target.  This keeps
// the bumper from chasing after a bad target forever.
int targetTime[ 2 ] = { 0, 0 };
int spreadTime[ 2 ] = { 0, 0 };

Vector2D block;
int num;

int n, turnNum;

double normSledDir()
{
	int q;
	double nDir;

	nDir = slist[0].dir;

	while(nDir < 0.0)
		nDir += 2*PI;

	q = nDir / (2*PI);
	while(q > 0)
	{
		nDir -= 2*PI;
		q--;
	}
	if(slist[0].dir == 6.28)
	{
		nDir = 0.0;
	}

	slist[0].dir = nDir;
}

double normSledDir2(double dir)
{
	int q;
	double nDir;

	nDir = dir;

	while(nDir < 0.0) {
		nDir += 2*PI;
	}

	q = nDir / (2*PI);
	while(q > 0)
	{
		nDir -= 2*PI;
		q--;
	}
	if(nDir == 6.28)
	{
		nDir = 0.0;
	}
	return(nDir);
}


/** Return a copy of x that's constrained to be between low and high. */
double clamp( double x, double low, double high )
{
	if ( x < low )
		x = low;
	if ( x > high )
		x = high;
	return x;
}

/** Compute a force vector that can be applied to a bumper to get it
	to run through the given target location.  Pos and vel are the
	bumper's current position and velocity.  Target is the position we
	want to run through and force is a returned vector that will move
	the bumper toward the target.  The function returns true until it
	looks like the next move will take us through the target
	location.  */
bool runTo( Vector2D const &pos,
		Vector2D const &vel, 
		Vector2D const &target, 
		Vector2D &force,
		double epsilon = 0.1 )
{
	// Compute a vector that will move self toward the target point.
	Vector2D direction = target - pos;
	double dist = direction.mag();

	// How much force do we have left to use in the force vector.
	//double resForce = BUMPER_FORCE_LIMIT - force.mag();

	// Normalize the direction we need to move.
	direction = direction.norm();

	// First, cancel out any movement that is perpendicular to the desired
	// movement direction.
	Vector2D perp = Vector2D( -direction.y, direction.x );
	force = -(perp * vel ) * perp;

	// Use all the residual force to move toward the target.
	double resForce = BUMPER_FORCE_LIMIT - force.mag();
	force = force + direction.limit( resForce );

	// See if this move will cross close enough to the target location.
	Vector2D nvel = ( vel + force ).limit( BUMPER_SPEED_LIMIT );
	double t = clamp( ( target - pos ) * nvel / (nvel * nvel), 0, 1 );
	if(isnan(force.x) || isnan(force.y)) {
    force.x = 0;
    force.y = 0;
  }
	if ( ( pos + t * nvel - target ).mag() < epsilon )
		return true;

	return false;
}

/** Return true if a puck at position pos is the responsibility of the
	bumper with index bdex. */
bool mySide( int bdex, Vector2D pos )
{
	if ( bdex == 0 && pos.y < 330 )
		return true;
	if ( bdex == 1 && pos.y > 470 )
		return true;
	return false;
}

int mostCrowdedBlock(int color, vector< Puck > plist, Vector2D &melhorBloco)
{
	vector<vector<int> > blocos;
	melhorBloco.x = melhorBloco.y = 0;
	int auxX, auxY;
	int numBlocos = FIELD_SIZE / BLOCK_SIZE;
	blocos.resize(numBlocos);

	// inicializando blocos
	for(int i=0; i<numBlocos; i++) {
		blocos[i].resize(numBlocos);
		for(int j=0; j<numBlocos; j++)
			blocos[i][j] = 0;
	}

	for(int i=0; i<plist.size(); i++) {
		auxX = plist[i].pos.x/BLOCK_SIZE;
		auxY = plist[i].pos.y/BLOCK_SIZE;
		if(plist[i].color == color) {
			blocos[auxX][auxY]++;
			//cerr << "AUXX " << plist[i].pos.x <<  " AuxY " << plist[i].pos.y << endl;
			// testa novo melhor bloco
			if(blocos[auxX][auxY] > blocos[melhorBloco.x][melhorBloco.y]) {
				melhorBloco.x = auxX;
				melhorBloco.y = auxY;
			}
		}
	}
	/*cerr << endl;
		if(blocos[melhorBloco.x][melhorBloco.y].count >= 3) {
		cerr << "PASSOU DE 3\n";
		cerr << melhorBloco.x << " " << melhorBloco.y << endl;
		cerr << blocos[melhorBloco.x][melhorBloco.y].count << endl;
		}*/

	return blocos[melhorBloco.x][melhorBloco.y];
}

// **************************************************************
// Le dados da entrada.
void leEntrada()
{
	int n;

	// Read all the puck locations.
	cin >> n;
	plist.resize( n );
	for ( int i = 0; i < n; i++ ) 
	{
		Puck &puck = plist[ i ];
		cin >> puck.pos.x >> puck.pos.y >> puck.vel.x >> puck.vel.y
			>> puck.color;
	}

	// Read all the bumper locations.
	cin >> n;
	blist.resize( n );
	for ( int i = 0; i < n; i++ ) 
	{
		Bumper &bumper = blist[ i ];
		cin >> bumper.pos.x >> bumper.pos.y >> bumper.vel.x >> bumper.vel.y;
	}

	// Read all the sled locations.
	cin >> n;
	slist.resize(n);
	sHist.resize(2);
	for ( int i = 0; i < n; i++ ) 
	{
		Sled &sled = slist[ i ];
		cin >> sled.pos.x >> sled.pos.y >> sled.dir;

		// Just ignore the path history for this sled.
		int m;
		cin >> m;
		sHist[i].resize(m);

		double dummy;
		Vector2D ultimoP;
		cin >> dummy;
		sHist[i][0].x=dummy;
		ultimoP.x=dummy;
		sledPM[i].x=dummy;
		cin >> dummy;
		sHist[i][0].y=dummy;
		ultimoP.y=dummy;
		sledPM[i].y=dummy;

		for ( int j = 1; j < m; j++ ) 
		{
			if(i==1)
			{




				cin >> dummy;
				sHist[i][j].x=dummy;
				if(fabs(ultimoP.x-dummy) > 180){
					//cerr<<"ultimoP.X:"<< ultimoP.x<<" dummy: "<<dummy<<endl;
					if(ultimoP.x<dummy){//precisa transformar para coordenadas negativas
						dummy-=800;
					}
					else{//transformar para coordenadas acima de 800
						dummy+=800;
					}
				}
				ultimoP.x=dummy;
				sledPM[i].x+=dummy;

				cin >> dummy;
				sHist[i][j].y=dummy;
				if(fabs(ultimoP.y-dummy) > 180){
					//							cerr<<"ultimoP.Y:"<< ultimoP.x<<" dummy: "<<dummy<<endl;
					if(ultimoP.y<dummy){//precisa transformar para coordenadas negativas
						dummy-=800;
					}
					else{//transformar para coordenadas acima de 800
						dummy+=800;
					}

				}
				ultimoP.y=dummy;
				sledPM[i].y+=dummy;


			}
			else
			{
				cin >> sHist[i][j].x;
				cin >> sHist[i][j].y;
			}
		}
		sledPM[i].x/=m;
		if(sledPM[i].x>=800)
			sledPM[i].x-=800;
		if(sledPM[i].x<0)
			sledPM[i].x+=800;

		sledPM[i].y/=m;
		if(sledPM[i].y>=800)
			sledPM[i].y-=800;	
		if(sledPM[i].y<0)
			sledPM[i].y+=800;
	}
}

// **************************************************************

void calculaBumpers()
{
	// Calculates the most crowded region with my color
	if(bstate[0] == DummyState)
	{
		num = mostCrowdedBlock(RED, plist, block);
		// center of the block
		block.x = block.x*BLOCK_SIZE+BLOCK_SIZE/2;
		block.y = block.y*BLOCK_SIZE+BLOCK_SIZE/2;
	}
	// Choose a move for each sled.
	for ( int i = 0; i < 2; i++ )
	{
		Bumper &bumper = blist[ i ];
		Vector2D force( 0, 0 );

		// Choose an up direction for this bumper.
		Vector2D up( 0, i == 0 ? -1 : 1 );

		// If my pucks number in the region is greater than 5 
		//if(num >= 3 && bstate[0] != SpreadMine ) {
		if(  bstate[i] == DummyState ) {
			bstate[ i ] = SearchBlock;
			target[ i ] = block;
			num = 0;
		}



    if ( bstate[ i ] == MoveOponent )
    {
      if ( (sledPM[1] - bumper.pos ).mag() < 50)
      {
        bstate[ i ] = SpreadGray;
        targetTime[ i ] = 0;
      } else
        // Move up and scoot a little to the side to prevent stupid behavior.
        //force = force + BUMPER_FORCE_LIMIT * (enemyS.pos - bumper.pos)/* + Vector2D( 0.01, 0 )*/;
   				target[i]=sledPM[1]; 
		
          for ( int j = 0; j < plist.size(); j++ ) {
            // Find a puck with my color not moving too fast, close
            // to me and kind of in the direction i'm moving.  Also,
            // make sure it's in the region block. Among these pucks,
            // pick the one that's closest to
            // the direction I should be heading.
            Vector2D direc = plist[ j ].pos - bumper.pos;
            if ( plist[ j ].color == BLUE &&
                plist[ j ].vel.mag() < 1 &&
                //direc.mag() < BLOCK_SIZE &&
                //( plist[ j ].pos - bumper.pos ).norm() * across > 0.6 &&
                // testa se cosseno do angulo interno eh maior que 0.6
                //( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) > 0.6 &&
               /* plist[ j ].pos.x >= ( block.x - BLOCK_SIZE/2 ) &&
                plist[ j ].pos.x < ( block.x + BLOCK_SIZE/2) &&
                plist[ j ].pos.y >= ( block.y - BLOCK_SIZE/2 ) &&
                plist[ j ].pos.y < ( block.y + BLOCK_SIZE/2 ) &&*/
                //( plist[ j ].pos - bumper.pos ).mag() < 115 &&
                ( plist[ j ].pos - sledPM[i] ).mag() < 115 &&
                /*( targetTime[ i ] <= 0 || */
                  // troca target se direcao de puck atual menor que target anterior
                  ( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) >
                  ( ( target[ i ] - bumper.pos ) * bumper.vel ) / ( ( target[i] - bumper.pos ).mag() * bumper.vel.mag())  ) {
              // Give 5 turns to hit the puck.
              // Hit it on its outside edge to bump it closer to the
              // center.
              //target[ i ] = plist[ j ].pos - across * 8 + up * 11;
              target[ i ] = plist[ j ].pos;
            }

          }
        	force = force + BUMPER_FORCE_LIMIT * (target[i] - bumper.pos) /*+ Vector2D( 0.01, 0 )*/;
 //         runTo( bumper.pos, bumper.vel, target[ i ], force ); 
		
		
		
		
		}


#if 0



		if ( bstate[ i ] == MoveOponent )
		{
			if ( (sledPM[1] - bumper.pos ).mag() < 50)
			{
				bstate[ i ] = SpreadGray;
				targetTime[ i ] = 0;
			} else
				// Move up and scoot a little to the side to prevent stupid behavior.
				//force = force + BUMPER_FORCE_LIMIT * (enemyS.pos - bumper.pos)/* + Vector2D( 0.01, 0 )*/;
				force = force + BUMPER_FORCE_LIMIT * (sledPM[1] - bumper.pos) + Vector2D( 0.01, 0 );
		}
#endif
		// Move right until we ge near the right edge.
		/* if ( bstate[ i ] == SeekRight && bumper.pos.x > 750 ) {
			 bstate[ i ] = SeekLeft;
			 }
		 */
		// Move left until we ge near the left edge.
		/*      if ( bstate[ i ] == SeekLeft && bumper.pos.x < 50 )
						if ( fabs( bumper.pos.y - 400 ) < 50 )
						bstate[ i ] = MoveUp;
						else
						bstate[ i ] = SeekRight;
		 */






      if ( bstate[ i ] == SpreadGray )
      {
        // Horizontal or vertical direction i'm going
        //Vector2D across;
        //if(bumper.vel.x > bumper.vel.y) {
        //				across.x = bumper.vel.x > 0 ? 1 : -1;
        //				across.y = 0;
        //} else {
        //				across.x = 0;
        //				across.y = bumper.vel.y > 0 ? 1 : -1;
        //}

        //Vector2D acrossH( bumper.vel.x > 0 ? 1 : -1, 0 );

        // If we don't have a target, find one.
        if ( targetTime[ i ] <= 0 ) {
          for ( int j = 0; j < plist.size(); j++ ) {
            // Find a puck with my color not moving too fast, close
            // to me and kind of in the direction i'm moving.  Also,
            // make sure it's in the region block. Among these pucks,
            // pick the one that's closest to
            // the direction I should be heading.
            Vector2D direc = plist[ j ].pos - bumper.pos;
            if ( plist[ j ].color == BLUE &&
                plist[ j ].vel.mag() < 1 &&
                //direc.mag() < BLOCK_SIZE &&
                //( plist[ j ].pos - bumper.pos ).norm() * across > 0.6 &&
                // testa se cosseno do angulo interno eh maior que 0.6
                ( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) > 0.6 &&
               /* plist[ j ].pos.x >= ( block.x - BLOCK_SIZE/2 ) &&
                plist[ j ].pos.x < ( block.x + BLOCK_SIZE/2) &&
                plist[ j ].pos.y >= ( block.y - BLOCK_SIZE/2 ) &&
                plist[ j ].pos.y < ( block.y + BLOCK_SIZE/2 ) &&*/
                ( plist[ j ].pos - bumper.pos ).mag() < 115 &&
                ( targetTime[ i ] <= 0 || 
                  // troca target se direcao de puck atual menor que target anterior
                  ( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) >
                  ( ( target[ i ] - bumper.pos ) * bumper.vel ) / ( ( target[i] - bumper.pos ).mag() * bumper.vel.mag()) ) ) {
              // Give 5 turns to hit the puck.
              targetTime[ i ] = 5;
              // Hit it on its outside edge to bump it closer to the
              // center.
              //target[ i ] = plist[ j ].pos - across * 8 + up * 11;
              target[ i ] = plist[ j ].pos;
            }

          }
        }
        // If w have a target, try to hit it.
        if ( targetTime[ i ] >= 0 )
        {
          if ( runTo( bumper.pos, bumper.vel, target[ i ], force ) ) {
            targetTime[ i ] = 0;
          } else
            targetTime[ i ] -= 1;
        } else {
          // Otherwise, just move across the field and angle toward
          // the center line a little bit.
          runTo( bumper.pos, bumper.vel, block, force );
          //force = force + ( acrossH - up * 0.05 ).norm() * BUMPER_FORCE_LIMIT;
        }

        if(targetTime[ i ] <= 0 && (sledPM[1] - bumper.pos ).mag() > 70){
          bstate[ i ] = MoveOponent;
        }
      }






#if 0

		if ( bstate[ i ] == SpreadGray )
		{
			// Go across the field and angle back toward the horizontal center
			// line.
			//      Vector2D across( bstate[ i ] == SeekRight ? 1 : -1, 0 );
			//      Vector2D across=enemyS.pos-bumper.pos;
			Vector2D across=sledPM[1]-bumper.pos;
			//( bstate[ i ] == SeekRight ? 1 : -1, 0 );

			// If we don't have a target, find one.
			if ( targetTime[ i ] <= 0 ) {
				for ( int j = 0; j < plist.size(); j++ )
					// Find a grey target that on my side of the center line, 
					// not moving too fast, close to me and kind of in the direction
					// i'm moving.  Also, make sure it's not too close to the top or
					// bottom.  Among these pucks, pick the one that's closest to
					// the direction I should be heading.
					if ( plist[ j ].color == GREY &&
							/*mySide( i, plist[ j ].pos ) &&*/
							plist[ j ].vel.mag() < 1 &&
							( plist[ j ].pos - bumper.pos ).mag() < 150 &&
							/* ( plist[ j ].pos - bumper.pos ).norm() * across > 0.6 &&*/
							/* fabs( plist[ j ].pos.y - 400 ) < 360 &&*/
							( targetTime[ i ] <= 0 || 
								( plist[ j ].pos - bumper.pos ).norm() * across >
								( target[ i ] - bumper.pos ).norm() * across ) ) {
						// Give 20 turns to hit the puck.
						targetTime[ i ] = 10;
						// Hit it on its outside edge to bump it closer to the
						// center.
						//target[ i ] = plist[ j ].pos - across * 25 + up * 44;
						//target[ i ] = plist[ j ].pos - across * 8 + up * 11;
						target[ i ] = plist[ j ].pos;
					}
			}

			//        if ( targetTime[ i ] >= 0 ) {
			//          force = force + BUMPER_FORCE_LIMIT * (target[i] - bumper.pos)/* + Vector2D( 0.01, 0 )*/;

			// If w have a target, try to hit it.
			if ( targetTime[ i ] >= 0 ) {
				if ( runTo( bumper.pos, bumper.vel, target[ i ], force ) ) {
					targetTime[ i ] = 0;
				} else
					targetTime[ i ] -= 1;
			} else {
				// Otherwise, just move across the field and angle toward
				// the center line a little bit.
				//         force = force + ( across - up * 0.05 ).norm() * BUMPER_FORCE_LIMIT;
				force = force + BUMPER_FORCE_LIMIT * (target[i] - bumper.pos)/* + Vector2D( 0.01, 0 )*/;
			}
			if ( (sledPM[1] - bumper.pos ).mag() > 50)
				bstate[ i ] = MoveOponent;

		}
#endif
		// Run to the center of the block
		if ( bstate[ i ] == SearchBlock )
		{
			//runTo( bumper.pos, bumper.vel, target[ i ], force );
			if ( runTo( bumper.pos, bumper.vel, target[ i ], force ) )
			{
				//				if( bumper.pos.x >= ( block.x - BLOCK_SIZE/2 ) &&
				//				 bumper.pos.x < ( block.x + BLOCK_SIZE/2) &&
				//				 bumper.pos.y >= ( block.y - BLOCK_SIZE/2 ) &&
				//				 bumper.pos.y < ( block.y + BLOCK_SIZE/2 ) ) {

				// Give 20 turns to spread the pucks
				spreadTime[ i ] = 50;
				bstate[ i ] = SpreadMine;
			}
			}

			if ( bstate[ i ] == SpreadMine )
			{
				// Horizontal or vertical direction i'm going
				//Vector2D across;
				//if(bumper.vel.x > bumper.vel.y) {
				//				across.x = bumper.vel.x > 0 ? 1 : -1;
				//				across.y = 0;
				//} else {
				//				across.x = 0;
				//				across.y = bumper.vel.y > 0 ? 1 : -1;
				//}

				//Vector2D acrossH( bumper.vel.x > 0 ? 1 : -1, 0 );

				// If we don't have a target, find one.
				if ( targetTime[ i ] <= 0 ) {
					for ( int j = 0; j < plist.size(); j++ ) {
						// Find a puck with my color not moving too fast, close
						// to me and kind of in the direction i'm moving.  Also,
						// make sure it's in the region block. Among these pucks,
						// pick the one that's closest to
						// the direction I should be heading.
						Vector2D direc = plist[ j ].pos - bumper.pos;
						if ( plist[ j ].color == RED &&
								plist[ j ].vel.mag() < 1 &&
								direc.mag() < BLOCK_SIZE &&
								//( plist[ j ].pos - bumper.pos ).norm() * across > 0.6 &&
								// testa se cosseno do angulo interno eh maior que 0.6
								( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) > 0.6 &&
								plist[ j ].pos.x >= ( block.x - BLOCK_SIZE/2 ) &&
								plist[ j ].pos.x < ( block.x + BLOCK_SIZE/2) &&
								plist[ j ].pos.y >= ( block.y - BLOCK_SIZE/2 ) &&
								plist[ j ].pos.y < ( block.y + BLOCK_SIZE/2 ) &&
								( targetTime[ i ] <= 0 || 
									// troca target se direcao de puck atual menor que target anterior
									( direc * bumper.vel ) / ( direc.mag() * bumper.vel.mag() ) >
									( ( target[ i ] - bumper.pos ) * bumper.vel ) / ( ( target[i] - bumper.pos ).mag() * bumper.vel.mag()) ) ) {
							// Give 5 turns to hit the puck.
							targetTime[ i ] = 5;
							// Hit it on its outside edge to bump it closer to the
							// center.
							//target[ i ] = plist[ j ].pos - across * 8 + up * 11;
							target[ i ] = plist[ j ].pos;
						}

					}
				}
				// If w have a target, try to hit it.
				if ( targetTime[ i ] >= 0 )
				{
					if ( runTo( bumper.pos, bumper.vel, target[ i ], force ) ) {
						targetTime[ i ] = 0;
					} else
						targetTime[ i ] -= 1;
				} else {
					// Otherwise, just move across the field and angle toward
					// the center line a little bit.
					runTo( bumper.pos, bumper.vel, block, force );
					//force = force + ( acrossH - up * 0.05 ).norm() * BUMPER_FORCE_LIMIT;
				}

				if( --spreadTime[ i ] <= 0 && targetTime[ i ] <= 0) {
					bstate[ i ] = DummyState;
				}
			}
			// Output the bumper's move.
			cout << force.x << " " << force.y << " ";
		}
}

Vector2D bestRegion()
{
	/////////////////////////////////////////////////////////////////////
	//INICIO DO CODIGO DE VERDADE, AQUI
	//PROGRAMAR O JOGADOR COMO O JOGADOR VERMELHO
	/////////////////////////////////////////////////////////////////////
	//ESTRATEGIA DA DIVISAO
	vector< vector <Bloco> > blocos; // cria matriz de blocos
	// 800x800 => tamanho da area do jogo
	// TAM_BLOCO definido no Utils.h 
	int NumBlocos = 800 / TAM_BLOCO;
	int index=0;
	// Define tamanho da matriz (NumBloco x NumBloco)
	// e inicializa posicoes com zero
	blocos.resize(NumBlocos);

	for(int i=0; i< blocos.size(); i++)
	{
		blocos[ i ].resize(NumBlocos);

		for(int j; j < blocos[i].size(); j++)
		{
			blocos.at(i)[ j ].Peso = 0;
		}
	}

	//Coloca os pesos dos blocos
	//Peso consiste numa soma de pucks seus. Se existir algum puck em 
	//algum dos blocos, o valor do bloco se torna negativo.
	for(int i=0; i< plist.size(); i++)
	{
		int auxX, auxY;
		int PesoAux, PesoValor;
		auxX = plist[ i ].pos.x / TAM_BLOCO;
		auxY = plist[ i ].pos.y / TAM_BLOCO;
		PesoAux = plist[ i ].color;


		if(PesoAux == RED)
		{
			// Peso para suas pecas
			PesoValor = 5;
		}
		else if (PesoAux == BLUE)
		{
			// Peso para peças do oponente 
			PesoValor = -1000;
		}
		else
		{
			// Peso para pecas cinzas
			PesoValor = 1;
		}

		// Indexacoes para manter a matriz de acordo com o
		// eixo X,Y do jogador Vermelho (inicio no canto inferior
		// direto)
		blocos[(NumBlocos-1)-auxY][auxX].Peso += PesoValor;
	}

	/////////////////////////////////////////////////////////////////////
	//SELECIONA O BLOCO COM MAIOR PESO
	Vector2D MelhorBloco;
	int MelhorPeso = 0;
	for(int i=0; i<blocos.size(); i++)
	{
		for(int j=0; j<blocos[i].size(); j++)
		{
			if(blocos[i][j].Peso > MelhorPeso)
			{
				MelhorBloco.x = i;
				MelhorBloco.y = j;
				MelhorPeso = blocos[i][j].Peso;
			}
		}
	}

	return(MelhorBloco);
}

int changeSledDirection(double x, double y)
{
	double currentDir,nx,ny,nDir,diff,diff2;
	static int p=0,xunxo=0;;

	if(sledState != GETTING_AWAY_EDGE)
		sledState = CHANGE_DIRECTION;	

	if(xunxo > 10)
	{
		sledDir = 0.0;
		xunxo = 0;
		if(sledState != GETTING_AWAY_EDGE)
			sledState = NOTHING;
		return(1);
	}

	currentDir = slist[0].dir;
	
//	nx = (x) - (slist[0].pos.x);
//	ny = (y) - (slist[0].pos.y);

//	nDir = acos(nx/sqrt((nx*nx)+(ny*ny)));

	nx = (x - 400.0) - (slist[0].pos.x - 400.0);
	ny = (y - 400.0) - (slist[0].pos.y - 400.0);

	nDir = atan(ny/nx);

	nDir = normSledDir2(nDir);

	diff = nDir - currentDir;

	diff2 = abs(diff);

	if(diff2 < 0.01)
	{
		sledDir = 0;
		
		if(sledState != GETTING_AWAY_EDGE)
			sledState = NOTHING;
		xunxo = 0;
		return(1);
	}

	p=0;

	if(diff < 0.0)
	{
		sledDir = diff;
	}
	else
	{
		sledDir = -1.0 * diff;
	}
	xunxo++;
	return(0);
}

int getAwayFromEdges()
{
	// It's near to an edge on the X axis.
	if(slist[0].pos.x < BIGGEST_R || slist[0].pos.x > (800.0 - BIGGEST_R))
	{
		sledState = GETTING_AWAY_EDGE;
	}
	// It's near to an edge on the Y axis.
	else if(slist[0].pos.y < BIGGEST_R || slist[0].pos.y > (800.0 - BIGGEST_R))
	{
		sledState = GETTING_AWAY_EDGE;
	}
	else
	{
		sledState = NOTHING;
		return(1);
	}

	if(sledState == GETTING_AWAY_EDGE)
	{
		if(changeSledDirection(400.0,400.0))
		{
			sledDir = 0;
		}
	}
	return(0);
}

int isInsideCircle(double x, double y, double cx, double cy, double r)
{
	double tmpx,tmpy;
	int nPos,i;
	double nx[4],ny[4];

	nPos = 0;
	nx[nPos] = x;
	ny[nPos] = y;
	nPos++;

	// Se estora o eixo x.
	if(x < r)
	{
		nx[nPos] = 800.0 + x;
		ny[nPos] = y;
		nPos++;

		if(y < r)
		{
			nx[nPos] = 800.0 + x;
			ny[nPos] = 800.0 + y;
			nPos++;
		}
		else if(y > (800.0 - r))
		{
			nx[nPos] = 800.0 + x;
			ny[nPos] = -1.0 * (800.0 - y);
			nPos++;
		}	
	}
	else if(x > (800.0 - r))
	{
		nx[nPos] = -1.0 * (800.0 - x);
		ny[nPos] = y;
		nPos++;
		
		if(y < r)
		{
			nx[nPos] = -1.0 * (800.0 - x);
			ny[nPos] = 800.0 + y;
			nPos++;
		}
		else if(y > (800.0 - r))
		{
			nx[nPos] = -1.0 * (800.0 - x);
			ny[nPos] = -1.0 * (800.0 - y);
			nPos++;
		}
	}
	
	// Se estora o eixo x.
	if(y < r)
	{
		nx[nPos] = x;
		ny[nPos] = 800.0 + y;
		nPos++;
	}
	else if(y > (800.0 - r))
	{
		nx[nPos] = x;
		ny[nPos] = -1.0 * (800.0 - y);
		nPos++;
	}

	for(i=0;i<nPos;i++)
	{
		tmpx = nx[i] - cx;
		tmpx *= tmpx;

		tmpy = ny[i] - cy;
		tmpy *= tmpy;

		// It's inside
		if((tmpx + tmpy) < (r*r))
		{
			return(1);
		}
		else
		{
			return(0);
		}
	}
}

int close(double cx, double cy, double r)
{
	int i,j,red,blue,grey;

	red = blue = grey = 0;

	for(i=0;i<plist.size();i++)
	{
		// It's inside
		if(isInsideCircle(plist[i].pos.x,plist[i].pos.y,cx,cy,r))
		{
			if(plist[i].color == RED)
			{
				red++;
			}
			else if(plist[i].color == BLUE)
			{
				blue++;
			}
			else if(plist[i].color == GREY)
			{
				grey++;
			}
		}
	}

	if(red && !blue && grey)
		return(1);
	else if(red && blue && (blue > red))
		return(1);
	else
		return(0);
}

int makeCircle(int loopSize,int direction,int loopGap,int giveUpPos)
{
	static int posCircle, posGap,p=0,erroRaio;
	static double yStart,x,y=100.0;
	static double r,d;
	static Vector2D center, start;
	double tmpx,tmpy,dirD,dirE;

	int startup = 12;
	int desiste = 0;
	

	if(sledState == GIVING_UP)
	{
		if(direction == LEFT)
			sledDir = -0.5;
		else
			sledDir = 0.5;

		sledState = CIRCLE;

		return(0);
	}

	// First move.
	if ( turnNum < startup ) 
	{
		sledState = CIRCLE;
		// Initially, try to move off-center a little bit.
		if ( turnNum < 6 )
			sledDir = -0.2;
		else
			sledDir = 0.2;

		posCircle = 0;
		posGap = 0;
		p = 10;
	}
	// If it's drawing the circle.
	else if(posCircle < loopSize - 1)
	{
		if(posCircle == 0)
		{
			p++;
			sledState = CIRCLE;
			start.x = slist[0].pos.x;
			start.y = slist[0].pos.y;
			
			dirD = slist[0].dir - (PI/2.0);
			dirE = slist[0].dir + (PI/2.0);

			// Normaliza direcao.
			dirD = normSledDir2(dirD);
			dirE = normSledDir2(dirE);

			if(direction == LEFT)
			{
				if(loopSize == 20)
				{
					center.x  = R_20 * cos(dirE) + slist[0].pos.x;
					center.y = R_20 * sin(dirE) + slist[0].pos.y;			
					r = R_20;
				}
				else if(loopSize == 30)
				{
					center.x  = R_30 * cos(dirE) + slist[0].pos.x;
					center.y = R_30 * sin(dirE) + slist[0].pos.y;
					r = R_30;
				}
				else if(loopSize == 40)
				{
					center.x  = R_40 * cos(dirE) + slist[0].pos.x;
					center.y = R_40 * sin(dirE) + slist[0].pos.y;
					r = R_40;
				}
			}
			else
			{
				if(loopSize == 20)
				{
					center.x  = R_20 * cos(dirD) + slist[0].pos.x;
					center.y = R_20 * sin(dirD) + slist[0].pos.y;			
					r = R_20;
				}
				else if(loopSize == 30)
				{
					center.x  = R_30 * cos(dirD) + slist[0].pos.x;
					center.y = R_30 * sin(dirD) + slist[0].pos.y;
					r = R_30;
				}
				else if(loopSize == 40)
				{
					center.x  = R_40 * cos(dirD) + slist[0].pos.x;
					center.y = R_40 * sin(dirD) + slist[0].pos.y;
					r = R_40;
				}
			}
		}
		// Nao precisa mais disso, mas to com preguica de tirar. ;P
		else if(posCircle == ((loopSize-1)/2))
		{
			tmpx = center.x - slist[0].pos.x;
			tmpy = center.y - slist[0].pos.y;
			r = sqrt((tmpx*tmpx) + (tmpy*tmpy));
		}

		else if(posCircle >= giveUpPos)
		{
			if(close(center.x,center.y,r))
			{
				desiste = 0;
			}
			else
			{
				desiste = 1;
			}
		}

		// Verifica se desiste.
		if(!desiste)
		{
			// Drive in a loop most of the time.
			sledDir = direction * 2 * acos( -1.0 ) / loopSize;

			if(p < 5)
			{
				sledDir = 0.0;
			}
			else
			{
				posCircle++;
			}
		}
		// Se desiste.
		else
		{
			posCircle = loopSize;
			if(direction == LEFT)
				sledDir = -0.5;
			else
				sledDir = 0.5;

			if(loopSize < 40)
				sledState = GIVING_UP;
		}
	}
	// If the circle was finished.
	else 
	{
		// Move the loop ahead.
		sledDir = 0;
		posGap++;

		// If the gap step is over, restart values.
		if(posGap == loopGap)
		{
			sledState = CIRCLE_ENDED;
			posCircle = 0;
			posGap = 0;
			p = 0;
			return(1);
		}
	}

	return(0);
}

int startCircle2(int &dir)
{
	int red_dir[3],blue_dir[3],grey_dir[3];
	int red_esq[3],blue_esq[3],grey_esq[3];
	int pGanhos_dir[3],pGanhos_esq[3];
	int pTirados_dir[3],pTirados_esq[3];
	int pPerdidos_dir[3],pPerdidos_esq[3];
	int i,lado,ganhaMais,tiraMais,quantoGanha,quantoTira,ladoFinal,circuloFinal;
	double cx_dir[3],cy_dir[3];
	double cx_esq[3],cy_esq[3];
	double dirD, dirE;
	double x,y,sx,sy;

	dirD = slist[0].dir - (PI/2.0);
	dirE = slist[0].dir + (PI/2.0);

	// Normaliza direcao.
	dirD = normSledDir2(dirD);
	dirE = normSledDir2(dirE);
			
//	sx = 45.0 * cos(slist[0].dir) + slist[0].pos.x;
//	sy = 45.0 * sin(slist[0].dir) + slist[0].pos.y;
	sx = slist[0].pos.x;
	sy = slist[0].pos.y;

	// Inicializa valores e calcula centros dos circulos.
	for(i=0;i<3;i++)
	{
		// Zera contadores.
		red_dir[i] = blue_dir[i] = grey_dir[i] = 0;
		red_esq[i] = blue_esq[i] = grey_esq[i] = 0;

		pGanhos_dir[i] = pGanhos_esq[i] = 0;
		pTirados_dir[i] = pTirados_esq[i] = 0;
		pPerdidos_dir[i] = pPerdidos_esq[i] = 0;;
	
		if(i==0)
		{
			cx_dir[i] = R_20 * cos(dirD) + sx;
			cy_dir[i] = R_20 * sin(dirD) + sy;
			
			cx_esq[i] = R_20 * cos(dirE) + sx;
			cy_esq[i] = R_20 * sin(dirE) + sy;
		}
		else if(i==1)
		{
			cx_dir[i] = R_30 * cos(dirD) + sx;
			cy_dir[i] = R_30 * sin(dirD) + sy;
			
			cx_esq[i] = R_30 * cos(dirE) + sx;
			cy_esq[i] = R_30 * sin(dirE) + sy;
		}
		else if(i==2)
		{
			cx_dir[i] = R_40 * cos(dirD) + sx;
			cy_dir[i] = R_40 * sin(dirD) + sy;
			
			cx_esq[i] = R_40 * cos(dirE) + sx;
			cy_esq[i] = R_40 * sin(dirE) + sy;
		}
	}

//	cerr << "[" << slist[0].pos.x << "," << slist[0].pos.y << "] - [" << cx_dir[0] << "," << cy_dir[0] << "] - [" << cx_esq[0] << "," << cy_esq[0] << "]" << endl;

	// Para cada puck.
	for(i=0;i<plist.size();i++)
	{
		x = plist[i].pos.x;
		y = plist[i].pos.y;

		// Para direita.
		// Para cada circulo se for necessario.
		if(isInsideCircle(x,y,cx_dir[0],cy_dir[0],R_20))
		{
			if(plist[i].color == RED)
			{
				red_dir[0]++;
				red_dir[1]++;
				red_dir[2]++;
			}
			else if(plist[i].color == BLUE)
			{
				blue_dir[0]++;
				blue_dir[1]++;
				blue_dir[2]++;
			}
			else if(plist[i].color == GREY)
			{
				grey_dir[0]++;
				grey_dir[1]++;
				grey_dir[2]++;
			}
		}
		else if(isInsideCircle(x,y,cx_dir[1],cy_dir[1],R_30))
		{
			if(plist[i].color == RED)
			{
				red_dir[1]++;
				red_dir[2]++;
			}
			else if(plist[i].color == BLUE)
			{
				blue_dir[1]++;
				blue_dir[2]++;
			}
			else if(plist[i].color == GREY)
			{
				grey_dir[1]++;
				grey_dir[2]++;
			}
		}
		else if(isInsideCircle(x,y,cx_dir[2],cy_dir[2],R_40))
		{
			if(plist[i].color == RED)
			{
				red_dir[2]++;
			}
			else if(plist[i].color == BLUE)
			{
				blue_dir[2]++;
			}
			else if(plist[i].color == GREY)
			{
				grey_dir[2]++;
			}
		}
		// Para esquerda.
		// Para cada circulo se for necessario.
		if(isInsideCircle(x,y,cx_esq[0],cy_esq[0],R_20))
		{
			if(plist[i].color == RED)
			{
				red_esq[0]++;
				red_esq[1]++;
				red_esq[2]++;
			}
			else if(plist[i].color == BLUE)
			{
				blue_esq[0]++;
				blue_esq[1]++;
				blue_esq[2]++;
			}
			else if(plist[i].color == GREY)
			{
				grey_esq[0]++;
				grey_esq[1]++;
				grey_esq[2]++;
			}
		}
		else if(isInsideCircle(x,y,cx_esq[1],cy_esq[1],R_30))
		{
			if(plist[i].color == RED)
			{
				red_esq[1]++;
				red_esq[2]++;
			}
			else if(plist[i].color == BLUE)
			{
				blue_esq[1]++;
				blue_esq[2]++;
			}
			else if(plist[i].color == GREY)
			{
				grey_esq[1]++;
				grey_esq[2]++;
			}
		}
		else if(isInsideCircle(x,y,cx_esq[2],cy_esq[2],R_40))
		{
			if(plist[i].color == RED)
			{
				red_esq[2]++;
			}
			else if(plist[i].color == BLUE)
			{
				blue_esq[2]++;
			}
			else if(plist[i].color == GREY)
			{
				grey_esq[2]++;
			}
		}
	}

	// Computa pontos perdidos e tirados para cada circulo
	// de cada lado.

	// Lado direito.
	for(i=0;i<3;i++)
	{
		if(red_dir[i] && !blue_dir[i] && grey_dir[i])
		{
			pGanhos_dir[i] = grey_dir[i];
		}

		if(red_dir[i] && blue_dir[i] && (blue_dir[i] > red_dir[i]))
		{
			pTirados_dir[i] = blue_dir[i];
			pPerdidos_dir[i] = red_dir[i];
		}
	}

	// Lado esquerdo.
	for(i=0;i<3;i++)
	{
		if(red_esq[i] && !blue_esq[i] && grey_esq[i])
		{
			pGanhos_esq[i] = grey_esq[i];
		}

		if(red_esq[i] && blue_esq[i] && (blue_esq[i] > red_esq[i]))
		{
			pTirados_esq[i] = blue_esq[i];
			pPerdidos_esq[i] = red_esq[i];
		}
	}
	
	// Toma a decisao de que lado deve fazer o circulo.
	// Ve em qual lado o maior circulo faz mais pontos.
	if(pGanhos_dir[2] > pGanhos_esq[2])
	{
		ganhaMais = RIGHT;
		quantoGanha = pGanhos_dir[2];
	}
	else
	{
		ganhaMais = LEFT;
		quantoGanha = pGanhos_esq[2];
	}

	if((pTirados_dir[2] - pPerdidos_dir[2]) > (pTirados_esq[2] - pPerdidos_esq[2]))
	{
		tiraMais = RIGHT;
		quantoTira = pTirados_dir[2] - pPerdidos_dir[2];
	}
	else
	{
		tiraMais = LEFT;
		quantoTira = pTirados_esq[2] - pPerdidos_esq[2];
	}

	if((quantoGanha <= 0) && (quantoTira <= 0))
	{
		return(0);
	}

	circuloFinal = 0;

	// Ve se é melhor ganhar pontos ou tirar pontos.
	if(quantoGanha >= quantoTira)
	{
		if(ganhaMais == RIGHT)
		{
			ladoFinal = RIGHT;
			if(pGanhos_dir[0] <= pGanhos_dir[1])
			{
				if(pGanhos_dir[1] < pGanhos_dir[2])
				{
					circuloFinal = 40;
				}
				else
				{
					circuloFinal = 30;
				}
			}
			else
			{
				circuloFinal = 20;
			}
		}
		else
		{
			ladoFinal = LEFT;
			if(pGanhos_esq[0] <= pGanhos_esq[1])
			{
				if(pGanhos_esq[1] < pGanhos_esq[2])
				{
					circuloFinal = 40;
				}
				else
				{
					circuloFinal = 30;
				}
			}
			else
			{
				circuloFinal = 20;
			}
		}
	}
	else
	{
		if(tiraMais == RIGHT)
		{
			ladoFinal = RIGHT;
			if((pTirados_dir[0] - pPerdidos_dir[0]) <= (pTirados_dir[1] - pPerdidos_dir[1]))
			{
				if((pTirados_dir[1] - pPerdidos_dir[1]) < (pTirados_dir[2] - pPerdidos_dir[2]))
				{
					circuloFinal = 40;
				}
				else
				{
					circuloFinal = 30;
				}
			}
			else
			{
				circuloFinal = 20;
			}
		}
		else
		{
			ladoFinal = LEFT;
			if((pTirados_esq[0] - pPerdidos_esq[0]) <= (pTirados_esq[1] - pPerdidos_esq[1]))
			{
				if((pTirados_esq[1] - pPerdidos_esq[1]) < (pTirados_esq[2] - pPerdidos_esq[2]))
				{
					circuloFinal = 40;
				}
				else
				{
					circuloFinal = 30;
				}
			}
			else
			{
				circuloFinal = 20;
			}
		}
	}

	dir = ladoFinal;
	if(ladoFinal == LEFT)
	{
//		cerr << "Dir: [Esq] - Tam: [" << circuloFinal << "] - Ganha: [" << quantoGanha << "] - Tira: [" << quantoTira << "]" << endl;
//		cerr << " - Pontos Ganhos: [" << pGanhos_esq[0] << "," << pGanhos_esq[1] << "," << pGanhos_esq[2] << "] - [" << pGanhos_dir[0] << "," << pGanhos_dir[1] << "," << pGanhos_dir[2] << "]" << endl;
	}
	else
	{
//		cerr << "Dir: [Dir] - Tam: [" << circuloFinal << "] - Ganha: [" << quantoGanha << "] - Tira: [" << quantoTira << "]" << endl;
//		cerr << " - Pontos Ganhos: [" << pGanhos_dir[0] << "," << pGanhos_dir[1] << "," << pGanhos_dir[2] << "] - [" << pGanhos_esq[0] << "," << pGanhos_esq[1] << "," << pGanhos_esq[2] << "]" << endl;
	}
	return(circuloFinal);
}

void calculaSleds()
{
	static Vector2D bestReg;
	static int dir=LEFT,p=0,tam;

	// Normaliza a direcao atual do sled.
	normSledDir();

	// Se por acaso nao faz nada, entao vai reto.
	sledDir = 0;

	// Avalia estados do sled.
	if(sledState == NOTHING)
	{
		tam = startCircle2(dir);

		if(turnNum == 0)
		{
			dir = LEFT;
			tam = 40;
			makeCircle(tam,dir,6,10);
		}
		else if(tam)
		{
			makeCircle(tam,dir,6,10);
		}
		else if(p == 15)
		{
			p=0;
			bestReg = bestRegion();
			bestReg.x *= TAM_BLOCO;
			bestReg.y *= TAM_BLOCO;
			//cerr << "BestRegion = [" << bestReg.x << "," << bestReg.y << "]" << endl;
			changeSledDirection(bestReg.x,bestReg.y);
		}
		else
		{
			p++;
		}
	}
	else if(sledState == CIRCLE)
	{
		makeCircle(tam,dir,6,10);
	}
	else if(sledState == GIVING_UP)
	{
		makeCircle(tam,dir,6,10);
	}
	else if(sledState == CIRCLE_ENDED)
	{
		bestReg = bestRegion();
		bestReg.x *= TAM_BLOCO;
		bestReg.y *= TAM_BLOCO;
		//cerr << "BestRegion = [" << bestReg.x << "," << bestReg.y << "]" << endl;
		changeSledDirection(bestReg.x,bestReg.y);
	}
	else if(sledState == CHANGE_DIRECTION)
	{
		changeSledDirection(bestReg.x,bestReg.y);
	}

	// Output the sled's move.
	cout << sledDir << endl;
}

int main() 
{
	cin >> turnNum;

	while ( turnNum >= 0 ) 
	{
		leEntrada();
		calculaBumpers();
		calculaSleds();
		cin >> turnNum;
	}
}
